home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / b / boot.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  13.8 KB  |  248 lines

  1. ;This is a simple boot sector that will load either MS-DOS or PC-DOS. It is not
  2.  
  3. ;self-reproducing, but it will be used as the foundation on which to build a
  4.  
  5. ;virus into a boot sector.
  6.  
  7.  
  8.  
  9. ;This segment is where the first operating system file (IBMBIO.COM or IO.SYS)
  10.  
  11. ;will be loaded and executed from. We don't know (or care) what is there, but
  12.  
  13. ;we do need the address to jump to defined in a separate segment so we can
  14.  
  15. ;execute a far jump to it.
  16.  
  17. DOS_LOAD        SEGMENT AT 0070H
  18.  
  19.                 ASSUME  CS:DOS_LOAD
  20.  
  21.  
  22.  
  23.                 ORG     0
  24.  
  25.  
  26.  
  27. LOAD:           DB      0               ;Start of the first operating system program
  28.  
  29.  
  30.  
  31. DOS_LOAD        ENDS
  32.  
  33.  
  34.  
  35.  
  36.  
  37. MAIN            SEGMENT BYTE
  38.  
  39.                 ASSUME  CS:MAIN,DS:MAIN,SS:NOTHING
  40.  
  41.  
  42.  
  43. ;This jump instruction is just here so we can compile this program as a COM
  44.  
  45. ;file. It is never actually executed, and never becomes a part of the boot
  46.  
  47. ;sector. Only the 512 bytes after the address 7C00 in this file become part of
  48.  
  49. ;the boot sector.
  50.  
  51.                 ORG     100H
  52.  
  53.  
  54.  
  55. START:          jmp     BOOTSEC
  56.  
  57.  
  58.  
  59. ;The following two definitions are BIOS RAM bytes which contain information
  60.  
  61. ;about the number and type of disk drives in the computer. These are needed by
  62.  
  63. ;the virus to decide on where to look to find drives to infect. They are not
  64.  
  65. ;normally needed by an ordinary boot sector.
  66.  
  67. ;
  68.  
  69. ;               ORG     0410H
  70.  
  71. ;
  72.  
  73. ;SYSTEM_INFO:    DB      ?                       ;System info byte: Take bits 6 & 7 and add 1 to get number of
  74.  
  75. ;                                                ;disk drives on this system (eg 01 = 2 drives)
  76.  
  77. ;
  78.  
  79. ;                ORG     0475H
  80.  
  81. ;
  82.  
  83. ;HD_COUNT:       DB      ?                       ;Number of hard drives in the system
  84.  
  85. ;
  86.  
  87. ;This area is reserved for loading the first sector of the root directory, when
  88.  
  89. ;checking for the existence of system files and loading the first system file.
  90.  
  91.  
  92.  
  93.                 ORG     0500H
  94.  
  95.  
  96.  
  97. DISK_BUF:       DW      ?                       ;Start of the buffer
  98.  
  99.  
  100.  
  101. ;Here is the start of the boot sector code. This is the chunk we will take out
  102.  
  103. ;of the compiled COM file and put it in the first sector on a 360K floppy disk.
  104.  
  105. ;Note that this MUST be loaded onto a 360K floppy to work, because the
  106.  
  107. ;parameters in the data area that follow are set up to work only with a 360K
  108.  
  109. ;disk!
  110.  
  111.  
  112.  
  113.                 ORG     7C00H
  114.  
  115.  
  116.  
  117. BOOTSEC:        JMP     BOOT                    ;Jump to start of boot sector code
  118.  
  119.  
  120.  
  121.                 ORG     7C03H                   ;This is needed because the jump will get coded as 2 bytes
  122.  
  123.  
  124.  
  125. DOS_ID:         DB      'EZBOOT  '              ;Name of this boot sector (8 bytes)
  126.  
  127. SEC_SIZE:       DW      200H                    ;Size of a sector, in bytes
  128.  
  129. SECS_PER_CLUST: DB      02                      ;Number of sectors in a cluster
  130.  
  131. FAT_START:      DW      1                       ;Starting sector for the first File Allocation Table (FAT)
  132.  
  133. FAT_COUNT:      DB      2                       ;Number of FATs on this disk
  134.  
  135. ROOT_ENTRIES:   DW      70H                     ;Number of root directory entries
  136.  
  137. SEC_COUNT:      DW      2D0H                    ;Total number of sectors on this disk
  138.  
  139. DISK_ID:        DB      0FDH                    ;Disk type code (This is 360KB)
  140.  
  141. SECS_PER_FAT:   DW      2                       ;Number of sectors per FAT
  142.  
  143. SECS_PER_TRK:   DW      9                       ;Sectors per track for this drive
  144.  
  145. HEADS:          DW      2                       ;Number of heads (sides) on this drive
  146.  
  147. HIDDEN_SECS:    DW      0                       ;Number of hidden sectors on the disk
  148.  
  149.  
  150.  
  151. DSKBASETBL:
  152.  
  153.                 DB      0                       ;Specify byte 1: step rate time, head unload time
  154.  
  155.                 DB      0                       ;Specify byte 2: Head load time, DMA mode
  156.  
  157.                 DB      0                       ;Wait time until motor turned off, in clock ticks
  158.  
  159.                 DB      0                       ;Bytes per sector (0=128, 1=256, 2=512, 3=1024)
  160.  
  161.                 DB      12H                     ;Last sector number (we make it large enough to handle 1.2/1.44 MB floppies)
  162.  
  163.                 DB      0                       ;Gap length between sectors for r/w operations, in bytes
  164.  
  165.                 DB      0                       ;Data transfer length when sector length not specified
  166.  
  167.                 DB      0                       ;Gap length between sectors for format operations, in bytes
  168.  
  169.                 DB      0                       ;Value stored in newly formatted sectors
  170.  
  171.                 DB      1                       ;Head settle time, in milliseconds (we set it small to speed operations)
  172.  
  173.                 DB      0                       ;Motor startup time, in 1/8 seconds
  174.  
  175.  
  176.  
  177. HEAD:           DB      0                       ;Current head to read from (scratch area used by boot sector)
  178.  
  179.  
  180.  
  181. ;Here is the start of the boot sector code
  182.  
  183.  
  184.  
  185. BOOT:           CLI                                     ;interrupts off
  186.  
  187.                 XOR     AX,AX                           ;prepare to set up segments
  188.  
  189.                 MOV     ES,AX                           ;set ES=0
  190.  
  191.                 MOV     SS,AX                           ;start stack at 0000:7C00
  192.  
  193.                 MOV     SP,OFFSET BOOTSEC
  194.  
  195.                 MOV     BX,1EH*4                        ;get address of disk
  196.  
  197.                 LDS     SI,SS:[BX]                      ;param table in ds:si
  198.  
  199.                 PUSH    DS
  200.  
  201.                 PUSH    SI                              ;save that address
  202.  
  203.                 PUSH    SS
  204.  
  205.                 PUSH    BX                              ;and its address
  206.  
  207.  
  208.  
  209.                 MOV     DI,OFFSET DSKBASETBL            ;and update default
  210.  
  211.                 MOV     CX,11                           ;values to the table stored here
  212.  
  213.                 CLD                                     ;direction flag cleared
  214.  
  215. DFLT1:          LODSB
  216.  
  217.                 CMP     BYTE PTR ES:[DI],0              ;anything non-zero
  218.  
  219.                 JNZ     SHORT DFLT2                     ;is not a default, so don't save it
  220.  
  221.                 STOSB                                   ;else put default value in place
  222.  
  223.                 JMP     SHORT DFLT3                     ;and go on to next
  224.  
  225. DFLT2:          INC     DI
  226.  
  227. DFLT3:          LOOP    DFLT1                           ;and loop until cx=0
  228.  
  229.  
  230.  
  231.                 MOV     AL,AH                           ;set ax=0
  232.  
  233.                 MOV     DS,AX                           ;set ds=0 so we can set disk tbl
  234.  
  235.                 MOV     WORD PTR [BX+2],AX              ;to @DSKBASETBL (ax=0 here)
  236.  
  237.                 MOV     WORD PTR [BX],OFFSET DSKBASETBL ;ok, done
  238.  
  239.                 STI                                     ;now turn interrupts on
  240.  
  241.                 INT     13H                             ;and reset disk drive system
  242.  
  243. ERROR1:         JC      ERROR1                          ;if an error, hang the machine
  244.  
  245.  
  246.  
  247. ;Here we look at the first file on the disk to see if it is the first MS-DOS or
  248.  
  249. ;PC-DOS system file, IO.SYS or IBMBIO.COM, respectively.
  250.  
  251. LOOK_SYS:
  252.  
  253.                 MOV     AL,BYTE PTR [FAT_COUNT]         ;get fats per disk
  254.  
  255.                 XOR     AH,AH
  256.  
  257.                 MUL     WORD PTR [SECS_PER_FAT]         ;multiply by sectors per fat
  258.  
  259.                 ADD     AX,WORD PTR [HIDDEN_SECS]       ;add hidden sectors
  260.  
  261.                 ADD     AX,WORD PTR [FAT_START]         ;add starting fat sector
  262.  
  263.  
  264.  
  265.                 PUSH    AX
  266.  
  267.                 MOV     WORD PTR [DOS_ID],AX            ;root dir, save it
  268.  
  269.  
  270.  
  271.                 MOV     AX,20H                          ;dir entry size
  272.  
  273.                 MUL     WORD PTR [ROOT_ENTRIES]         ;dir size in ax
  274.  
  275.                 MOV     BX,WORD PTR [SEC_SIZE]          ;sector size
  276.  
  277.                 ADD     AX,BX                           ;add one sector
  278.  
  279.                 DEC     AX                              ;decrement by 1
  280.  
  281.                 DIV     BX                              ;ax=# sectors in root dir
  282.  
  283.                 ADD     WORD PTR [DOS_ID],AX            ;DOS_ID=start of data
  284.  
  285.                 MOV     BX,OFFSET DISK_BUF              ;set up disk read buffer at 0000:0500
  286.  
  287.                 POP     AX
  288.  
  289.                 CALL    CONVERT                         ;and go convert sequential sector number to bios data
  290.  
  291.                 MOV     AL,1                            ;prepare for a disk read for 1 sector
  292.  
  293.                 CALL    READ_DISK                       ;go read it
  294.  
  295.  
  296.  
  297.                 MOV     DI,BX                           ;compare first file on disk with
  298.  
  299.                 MOV     CX,11                           ;required file name
  300.  
  301.                 MOV     SI,OFFSET SYSFILE_1             ;of first system file for PC DOS
  302.  
  303.                 REPZ    CMPSB
  304.  
  305.                 JZ      SYSTEM_THERE                    ;ok, found it, go load it
  306.  
  307.  
  308.  
  309.                 MOV     DI,BX                           ;compare first file with
  310.  
  311.                 MOV     CX,11                           ;required file name
  312.  
  313.                 MOV     SI,OFFSET SYSFILE_2             ;of first system file for MS DOS
  314.  
  315.                 REPZ    CMPSB
  316.  
  317. ERROR2:         JNZ     ERROR2                          ;not the same - an error, so hang the machine
  318.  
  319.  
  320.  
  321. ;Ok, system file is there, so load it
  322.  
  323. SYSTEM_THERE:
  324.  
  325.                 MOV     AX,WORD PTR [DISK_BUF+1CH]      ;get file size of IBMBIO.COM/IO.SYS
  326.  
  327.                 XOR     DX,DX
  328.  
  329.                 DIV     WORD PTR [SEC_SIZE]             ;and divide by sector size
  330.  
  331.                 INC     AL                              ;ax=number of sectors to read
  332.  
  333.                 MOV     BP,AX                           ;store that number in BP
  334.  
  335.                 MOV     AX,WORD PTR [DOS_ID]            ;get sector number of start of data
  336.  
  337.                 PUSH    AX
  338.  
  339.                 MOV     BX,700H                         ;set disk read buffer to 0000:0700
  340.  
  341. RD_BOOT1:       MOV     AX,WORD PTR [DOS_ID]            ;and get sector to read
  342.  
  343.                 CALL    CONVERT                         ;convert to bios Trk/Cyl/Sec info
  344.  
  345.                 MOV     AL,1                            ;read one sector
  346.  
  347.                 CALL    READ_DISK                       ;go read the disk
  348.  
  349.                 SUB     BP,1                            ;subtract 1 from number of sectors to read
  350.  
  351.                 JZ      DO_BOOT                         ;and quit if we're done
  352.  
  353.                 ADD     WORD PTR [DOS_ID],1             ;add sectors read to sector to read
  354.  
  355.                 ADD     BX,WORD PTR [SEC_SIZE]          ;and update buffer address
  356.  
  357.                 JMP     RD_BOOT1                        ;then go for another
  358.  
  359.  
  360.  
  361.  
  362.  
  363. ;Ok, the first system file has been read in, now transfer control to it
  364.  
  365. DO_BOOT:
  366.  
  367.                 MOV     CH,BYTE PTR [DISK_ID]           ;Put drive type in ch
  368.  
  369.                 MOV     DL,BYTE PTR [DRIVE]             ;Drive number in dl
  370.  
  371.                 POP     BX
  372.  
  373.                 JMP     FAR PTR LOAD                    ;and transfer control to the first system file
  374.  
  375.  
  376.  
  377.  
  378.  
  379. ;Convert sequential sector number in ax to BIOS Track, Head, Sector information.
  380.  
  381. ;Save track number in DX, sector number in CH,
  382.  
  383. CONVERT:
  384.  
  385.                 XOR     DX,DX
  386.  
  387.                 DIV     WORD PTR [SECS_PER_TRK]         ;divide ax by sectors per track
  388.  
  389.                 INC     DL                              ;dl=sector number to start read on, al=track/head count
  390.  
  391.                 MOV     CH,DL                           ;save it here
  392.  
  393.                 XOR     DX,DX
  394.  
  395.                 DIV     WORD PTR [HEADS]                ;divide ax by head count
  396.  
  397.                 MOV     BYTE PTR [HEAD],DL              ;dl=head number, save it
  398.  
  399.                 MOV     DX,AX                           ;ax=track number, save it in dx
  400.  
  401.                 RET
  402.  
  403.  
  404.  
  405.  
  406.  
  407. ;Read the disk for the number of sectors in al, into the buffer es:bx, using
  408.  
  409. ;the track number in DX, the head number at HEAD, and the sector
  410.  
  411. ;number at CH.
  412.  
  413. READ_DISK:
  414.  
  415.                 MOV     AH,2                            ;read disk command
  416.  
  417.                 MOV     CL,6                            ;shift possible upper 2 bits of track number to
  418.  
  419.                 SHL     DH,CL                           ;the high bits in dh
  420.  
  421.                 OR      DH,CH                           ;and put sector number in the low 6 bits
  422.  
  423.                 MOV     CX,DX
  424.  
  425.                 XCHG    CH,CL                           ;ch (0-5) = sector, cl, ch (6-7) = track
  426.  
  427.                 MOV     DL,BYTE PTR [DRIVE]             ;get drive number from here
  428.  
  429.                 MOV     DH,BYTE PTR [HEAD]              ;and head number from here
  430.  
  431.                 INT     13H                             ;go read the disk
  432.  
  433. ERROR3:         JC      ERROR3                          ;hang in case of an error
  434.  
  435.                 RET
  436.  
  437.  
  438.  
  439. ;Move data that doesn't change from this boot sector to the one read in at
  440.  
  441. ;DISK_BUF. That includes everything but the DRIVE ID (at offset 7DFDH) and
  442.  
  443. ;the data area at the beginning of the boot sector.
  444.  
  445. MOVE_DATA:
  446.  
  447.                 MOV     SI,OFFSET DSKBASETBL            ;Move all of the boot sector code after the data area
  448.  
  449.                 MOV     DI,OFFSET DISK_BUF + (OFFSET DSKBASETBL - OFFSET BOOTSEC)
  450.  
  451.                 MOV     CX,OFFSET DRIVE - OFFSET DSKBASETBL
  452.  
  453.                 REP     MOVSB
  454.  
  455.                 MOV     SI,OFFSET BOOTSEC               ;Move the initial jump and the sector ID
  456.  
  457.                 MOV     DI,OFFSET DISK_BUF
  458.  
  459.                 MOV     CX,11
  460.  
  461.                 REP     MOVSB
  462.  
  463.                 RET
  464.  
  465.  
  466.  
  467.  
  468.  
  469. SYSFILE_1:      DB      'IBMBIO  COM'                   ;PC DOS System file
  470.  
  471. SYSFILE_2:      DB      'IO      SYS'                   ;MS DOS System file
  472.  
  473.  
  474.  
  475.                 ORG     7DFDH
  476.  
  477.  
  478.  
  479. DRIVE:          DB      0                               ;Drive number, used in disk reads, etc.
  480.  
  481. BOOT_ID:        DW      0AA55H                          ;Boot sector ID word
  482.  
  483.  
  484.  
  485.  
  486.  
  487. MAIN            ENDS
  488.  
  489.  
  490.  
  491.  
  492.  
  493.                 END START
  494.  
  495.